package com.gpframework.module.service.wages.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gpframework.common.enums.YesNoEnum;
import com.gpframework.common.exception.BaseException;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.module.service.wages.IGzGenerateMonthlyPayrollService;
import com.gpframework.module.system.mapper.SysDictDataMapper;
import com.gpframework.module.wages.domain.*;
import com.gpframework.module.wages.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class GzGenerateMonthlyPayrollServiceImpl implements IGzGenerateMonthlyPayrollService {

    @Resource
    private   IGzAttendanceManagementService iGzAttendanceManagementService;
    //月度休假
    @Resource
    private  IGzMonthlyLeaveService iGzMonthlyLeaveService;
    //员工评定
    @Resource
    private  IGzEmployeeEvaluationService iGzEmployeeEvaluationService;

    @Resource
    //档口及办公室工资
    private  IGzOfficeSalaryService iGzOfficeSalaryService;

    @Resource
    //中转人员工资
    private  IGzTransferService iGzTransferService;
    @Resource
    //仓库人员工资
    private  IGzWarehousePersonnelService iGzWarehousePersonnelService;

    @Autowired
    private IGzWarehouseEvaluationService iGzWarehouseEvaluationService;

    @Resource
    private  IGzMonthlyPickupService iGzMonthlyPickupService;
    @Resource
    private  IGzMonthlyReceiptOfGoodsService iGzMonthlyReceiptOfGoodsService;
    @Resource
    private  IGzFleetMonthlyRecordService iGzFleetMonthlyRecordService;

    @Resource
    private  IGzPersonnelVersionService iGzPersonnelVersionService;

    @Autowired
    private IGzSalaryLevelTransferWarehouseWorkersService iGzSalaryLevelTransferWarehouseWorkersService;

    @Autowired
    private IGzWarehouseWorkerSalaryLevelService iGzWarehouseWorkerSalaryLevelService;

    //公司总销售
    @Autowired
    private IGzTotalSalesOfTheCompanyService iGzTotalSalesOfTheCompanyService;
    @Autowired
    private IGzMonthlySalesCommissionService iGzMonthlySalesCommissionService;

    //广州人事基本工资
    @Autowired
    private  IGzHolidaysService iGzHolidaysService;


    @Autowired
    private SysDictDataMapper sysDictDataMapper;



    @Override
    public void generateOfficeSalary(Date month,List<GzPersonnelFoundation> gzPersonnelFoundationList) {

        //删除
        iGzOfficeSalaryService.delelteMonth(month);

        //生成工资单
        List<GzOfficeSalary> gzOfficeSalaries=new ArrayList<>();

        //数据封装
        for (GzPersonnelFoundation gzPersonnelFoundation : gzPersonnelFoundationList) {
            GzOfficeSalary gzOfficeSalary=new GzOfficeSalary();
            gzOfficeSalary.setUserId(gzPersonnelFoundation.getId());
            gzOfficeSalary.setMonth(month);
            gzOfficeSalary.setDepartmentName(gzPersonnelFoundation.getDepartmentName());
            gzOfficeSalary.setName(gzPersonnelFoundation.getName());
            gzOfficeSalary.setBaseSalary(gzPersonnelFoundation.getBasicSalary());
            gzOfficeSalary.setSubsidyBase(gzPersonnelFoundation.getOtherSubsidies());
            gzOfficeSalary.setSubsidy(gzPersonnelFoundation.getPersonalPortionOfSocialSecurity());

            //评定奖金
            GzEmployeeEvaluation gzEmployeeEvaluation = iGzEmployeeEvaluationService.getOne(new QueryWrapper<GzEmployeeEvaluation>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));
            if (gzEmployeeEvaluation==null || gzEmployeeEvaluation.getMonthlyEvaluationBonus()==null){
                throw new BaseException("请在员工评定，输入月度评定奖金");
            }
            gzOfficeSalary.setMonthlyEvaluationBonus(gzEmployeeEvaluation.getMonthlyEvaluationBonus());
            gzOfficeSalary.setEvaluateBonus(gzEmployeeEvaluation.getEvaluationCriteriaBonus());

            //考勤管理
            /** 应出勤天数 */
            gzOfficeSalary.setRequiredAttendanceDays(gzPersonnelFoundation.getRequireDateNdancedays());
            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));
            if ( attendanceManagement==null  || attendanceManagement.getAttendanceDays()==null){
                throw new BaseException("请在考勤管理,输入应出勤天数");
            }

            //满勤 才有全勤奖
            gzOfficeSalary.setFullAttendanceAward(BigDecimal.valueOf(0));
            if(attendanceManagement.getAttendanceDays().equals(gzPersonnelFoundation.getRequireDateNdancedays())){
                gzOfficeSalary.setFullAttendanceAward(attendanceManagement.getFullAttendanceBonus());
            }

            gzOfficeSalary.setAbsenceDays(attendanceManagement.getAbsenceDays());
            gzOfficeSalary.setPaidLeaveCompany(attendanceManagement.getPaidLeaveCompany());

                gzOfficeSalary.setAttendanceDays(attendanceManagement.getAttendanceDays());
                gzOfficeSalary.setTravelSubsidy(attendanceManagement.getTravelSubsidy());
                gzOfficeSalary.setOvertimeLate(attendanceManagement.getOvertimeLate());
                gzOfficeSalary.setMealFeeDeduction(attendanceManagement.getMealFeeDeduction());


            //出勤工资 实发补贴 销售奖
            //if (!gzMonthlyLeave.getRequireDateNdancedays().equals(0)){
                //出勤工资=(基础工资/应出勤天数)*出勤天数


            try {
                gzOfficeSalary.setAttendanceSalary(gzPersonnelFoundation.getBasicSalary().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            } catch (Exception e) {
                throw new BaseException("请生成考勤管理");
            }


            //gzOfficeSalary.setAttendanceSalary(gzPersonnelFoundation.getBasicSalary().multiply(BigDecimal.valueOf(gzAttendanceManagement.getAttendanceDays())).divide(new BigDecimal(gzMonthlyLeave.getRequireDateNdancedays()), 2, RoundingMode.HALF_UP));
                //实发补贴=(补贴基数/出勤天数)应出勤天数
            gzOfficeSalary.setPaidSubsidies(gzPersonnelFoundation.getOtherSubsidies().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            //}

            //销售奖
            //GzTotalSalesOfTheCompany theCompanyServiceOne = iGzTotalSalesOfTheCompanyService.getOne(new QueryWrapper<GzTotalSalesOfTheCompany>().eq("month", month));
            //月度销售提成
            GzMonthlySalesCommission gzMonthlySalesCommission = iGzMonthlySalesCommissionService.getOne(new QueryWrapper<GzMonthlySalesCommission>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));
            if (gzMonthlySalesCommission ==null){
                throw new BaseException("请先生成销售月度提成");
            }

            String dictLabelString = sysDictDataMapper.selectDictLabel("completion_bonus_value", "销售完成奖金值");
            if (dictLabelString==null){
                throw new BaseException("字典中未设置销售完成奖金值");
            }
            //销售完成奖金值
            BigDecimal dictLabel = new BigDecimal(dictLabelString);

            //没有销售等级 办公室人员 直接销售奖为0
            if (StringUtils.isEmpty(gzMonthlySalesCommission.getRatingIevel())){
                gzOfficeSalary.setSalesAward(BigDecimal.ZERO);
            }

            if ("A".equals(gzMonthlySalesCommission.getRatingIevel())){
                if (gzMonthlySalesCommission.getMonthlyTotalSales()==null||  gzMonthlySalesCommission.getDailyBonus() ==null )  {
                    throw new BaseException("销售月度提成 进行计算 月度总销售额");
                }
                if (gzMonthlySalesCommission.getMonthlyTotalSales()!=null && gzMonthlySalesCommission.getDailyBonus() != null &&gzMonthlySalesCommission.getSalesGear()!=null){

                    // 月度总销售/100000 -（月度总销售额/起征点 +1）
                    //月度总销售额/100000-销售等级
                    //BigDecimal averageValue = (gzMonthlySalesCommission.getMonthlyTotalSales().divide(BigDecimal.valueOf(100000), 2, RoundingMode.HALF_UP)).subtract();
                    //(几档 * 档次) +日奖金
                    if (gzMonthlySalesCommission.getSalesLevel()==null){
                        gzMonthlySalesCommission.setSalesLevel(BigDecimal.ONE);
                    }

                    gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus()));

                }
            }

            if (("B").equals(gzMonthlySalesCommission.getRatingIevel())){
                if (gzMonthlySalesCommission.getMonthlyTotalSales() != null && gzMonthlySalesCommission.getDailyBonus() != null && gzMonthlySalesCommission.getCommissionRatio() != null){

                    if (gzMonthlySalesCommission.getComplete() ==null || gzMonthlySalesCommission.getComplete().equals(3)){
                        throw new  BaseException("请去月度销售里 评定是否 完成");
                    }


                    //未完成 没有销售奖
                    if(gzMonthlySalesCommission.getComplete().equals(0)){
                        gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus()));
                    }
                    //完成 有销售奖  销售完成奖金值 1000
                    if(gzMonthlySalesCommission.getComplete().equals(1)){
                        gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus().add(dictLabel)));
                    }


             }
            }

            if (("C").equals(gzMonthlySalesCommission.getRatingIevel())){
                if (gzMonthlySalesCommission.getMonthlyTotalSales() != null && gzMonthlySalesCommission.getDailyBonus() != null && gzMonthlySalesCommission.getCommissionRatio() != null){
                    //提成比例
                    BigDecimal commissionRatio =gzMonthlySalesCommission.getCommissionRatio();
                    BigDecimal startingPointTaxation = gzMonthlySalesCommission.getStartingPointTaxation();
                    //（月度总销售-起征点+100000）*提成比例+日奖金
                    if (gzMonthlySalesCommission.getSalesLevel()==null){
                        gzMonthlySalesCommission.setSalesLevel(BigDecimal.ONE);
                    }
                    if (gzMonthlySalesCommission.getComplete() ==null || gzMonthlySalesCommission.getComplete().equals(3)){
                        throw new  BaseException("请先生成月度销售里 评定是否 完成");
                    }

                    //未完成 没有销售奖
                    if(gzMonthlySalesCommission.getComplete().equals(0)){
                        gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus()));
                    }
                    //完成 有销售奖  销售完成奖金值 1000
                    if(gzMonthlySalesCommission.getComplete().equals(1)){
                        gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus().add(dictLabel)));
                    }

              }
            }

            if (("D").equals(gzMonthlySalesCommission.getRatingIevel())){
                if(gzMonthlySalesCommission.getComplete().equals(1)){
                    gzOfficeSalary.setSalesAward(new BigDecimal(500));
                }
            }

            if (("E").equals(gzMonthlySalesCommission.getRatingIevel())){
                if (gzMonthlySalesCommission.getMonthlyTotalSales()==null||  gzMonthlySalesCommission.getDailyBonus() ==null )  {
                    throw new BaseException("请先生成销售月度提成 进行计算 月度总销售额");
                }
                if (gzMonthlySalesCommission.getMonthlyTotalSales()!=null && gzMonthlySalesCommission.getDailyBonus() != null &&gzMonthlySalesCommission.getSalesGear()!=null){
                    //(几档 * 档次) +日奖金
                    if (gzMonthlySalesCommission.getSalesLevel()==null){
                        gzMonthlySalesCommission.setSalesLevel(BigDecimal.ONE);
                    }
                    gzOfficeSalary.setSalesAward(gzMonthlySalesCommission.getSalesLevel().multiply(gzMonthlySalesCommission.getSalesGear()).add(gzMonthlySalesCommission.getDailyBonus()));

                }
                if (gzMonthlySalesCommission.getComplete() ==null){
                    throw new  BaseException("请先生成月度销售 评定是否 完成");
                }
                //完成了再加500
                if(gzMonthlySalesCommission.getComplete().equals(1)){
                    gzOfficeSalary.setSalesAward(gzOfficeSalary.getSalesAward().add(new BigDecimal(500)));
                }

            }


            //// F:（某员工销售档次+1/3销售档次）*（部门一所在销售等级）+部门一所在日奖金+（某员工1/3销售档次）*（部门二所在销售等级）
            if (("F").equals(gzMonthlySalesCommission.getRatingIevel())){
                //查找相同姓名的员工
                List<GzMonthlySalesCommission> list = iGzMonthlySalesCommissionService.list(new QueryWrapper<GzMonthlySalesCommission>().eq("month", month).eq("name", gzPersonnelFoundation.getName()));
                if (list.size() > 1) {
                    GzMonthlySalesCommission gzMonthlySalesCommission1 = list.get(0);
                    GzMonthlySalesCommission gzMonthlySalesCommission2 = list.get(1);
                    if (gzMonthlySalesCommission1.getMonthlyTotalSales()==null||  gzMonthlySalesCommission1.getDailyBonus() ==null )  {
                        throw new BaseException("该员工部门一 销售月度提成 请进行计算 ");
                    }
                    if (gzMonthlySalesCommission2.getMonthlyTotalSales()==null||  gzMonthlySalesCommission2.getDailyBonus() ==null )  {
                        throw new BaseException("该员工部门二 销售月度提成 请进行计算");
                    }
                    if (gzMonthlySalesCommission1.getSalesLevel()==null){
                        gzMonthlySalesCommission1.setSalesLevel(BigDecimal.ONE);
                    }
                    if (gzMonthlySalesCommission2.getSalesLevel()==null){
                        gzMonthlySalesCommission2.setSalesLevel(BigDecimal.ONE);
                    }
                    // F:（某员工部门一销售档次+部门二销售档次）*（部门一所在销售等级）+部门一所在日奖金+（部门二销售档次）*（部门二所在销售等级）
                    if (gzMonthlySalesCommission1.getMonthlyTotalSales()!=null && gzMonthlySalesCommission1.getDailyBonus() != null &&gzMonthlySalesCommission1.getSalesGear()!=null &&gzMonthlySalesCommission2.getSalesGear()!=null) {
                        //部门一销售档次
                        BigDecimal salesGear1 = gzMonthlySalesCommission1.getSalesGear();
                        //部门一所在销售等级
                        BigDecimal salesLevel1 = gzMonthlySalesCommission1.getSalesLevel();
                        // 部门二 销售档次
                        BigDecimal salesGear2= gzMonthlySalesCommission2.getSalesGear();
                        //部门二所在销售等级
                        BigDecimal salesLevel2 = gzMonthlySalesCommission2.getSalesLevel();


                        //(某员工部门一销售档次+部门二 销售档次 ）*（部门一所在销售等级）+部门一所在日奖金
                        BigDecimal one = ((salesLevel1).multiply(salesGear1.add(salesGear2)).add(gzMonthlySalesCommission1.getDailyBonus()));
                        //(部门二 销售档次）*（部门二所在销售等级）
                        BigDecimal two = salesGear2.multiply(salesLevel2);
                        gzOfficeSalary.setSalesAward(one.add(two));
                    }

                } else {

                }

            }


            //实际发放
            gzOfficeSalary.setActualSalaryPaid(realityGzOfficeSalary(gzOfficeSalary));

            //合计
            gzOfficeSalary.setAmountTo(amountToGzOfficeSalary(gzOfficeSalary));
            gzOfficeSalaries.add(gzOfficeSalary);
        }
        iGzOfficeSalaryService.saveOrUpdateBatch(gzOfficeSalaries);
    }


    private BigDecimal amountToGzOfficeSalary(GzOfficeSalary gzOfficeSalary){
        BigDecimal amountTo=new BigDecimal(0);

        amountTo=amountTo.add(gzOfficeSalary.getAttendanceSalary());
        amountTo=amountTo.add(gzOfficeSalary.getSubsidyBase());
        amountTo=amountTo.add(gzOfficeSalary.getTravelSubsidy());
        amountTo=amountTo.add(gzOfficeSalary.getFullAttendanceAward());

        //变化的
        amountTo=amountTo.add(gzOfficeSalary.getSalesAward());
        amountTo=amountTo.add(gzOfficeSalary.getMonthlyEvaluationBonus());

        //扣的
        amountTo=amountTo.add(gzOfficeSalary.getOvertimeLate());
        amountTo=amountTo.add(gzOfficeSalary.getMealFeeDeduction());
        amountTo=amountTo.add(gzOfficeSalary.getSubsidy());
        return amountTo;

    }

    private BigDecimal realityGzOfficeSalary(GzOfficeSalary gzOfficeSalary){
        BigDecimal reality=new BigDecimal(0);
        reality=reality.add(gzOfficeSalary.getAttendanceSalary());
        reality=reality.add(gzOfficeSalary.getSubsidyBase());
        reality=reality.add(gzOfficeSalary.getTravelSubsidy());
        reality=reality.add(gzOfficeSalary.getFullAttendanceAward());


        reality=reality.add(gzOfficeSalary.getSalesAward());
        reality=reality.add(gzOfficeSalary.getMonthlyEvaluationBonus());

        reality=reality.add(gzOfficeSalary.getOvertimeLate());
        reality=reality.add(gzOfficeSalary.getMealFeeDeduction());
        reality=reality.add(gzOfficeSalary.getSubsidy());
        return reality;
    }


    //生成中转工资条
    @Override
    public void generateTransferPayroll(Date month, List<GzPersonnelFoundation> gzTransfers) {

        //删除
        iGzTransferService.delelteMonth(month);

        List<GzTransfer> gzTransferList=new ArrayList<>();
        //数据封装 中转
        for (GzPersonnelFoundation gzPersonnelFoundation : gzTransfers) {
            GzTransfer gzTransfer=new GzTransfer();
            //基本模块
            gzTransfer.setUserId(gzPersonnelFoundation.getId());
            gzTransfer.setMonth(month);
            gzTransfer.setDepartmentName(gzPersonnelFoundation.getDepartmentName());
            gzTransfer.setName(gzPersonnelFoundation.getName());
            gzTransfer.setBaseSalary(gzPersonnelFoundation.getBasicSalary());
            gzTransfer.setPostWage(gzPersonnelFoundation.getPostWage());
            gzTransfer.setManagementAllowance(gzPersonnelFoundation.getManagementAllowance());
            gzTransfer.setHouseAllowance(gzPersonnelFoundation.getHouseaLlowance());
            gzTransfer.setSocialSecuritySubsidies(gzPersonnelFoundation.getSocialSecuritySubsidies());
            gzTransfer.setAchievementBonus(gzPersonnelFoundation.getAchievementBonus());
            gzTransfer.setEvaluateBonus(gzPersonnelFoundation.getEvaluationCriteriaBonus());
            gzTransfer.setIncreaseTemperatureSubsidy(gzPersonnelFoundation.getIncreaseTemperatureSubsidy());

            gzTransfer.setSubsidy(gzPersonnelFoundation.getPersonalPortionOfSocialSecurity());
            //应出勤天数
            gzTransfer.setRequiredAttendanceDays(gzPersonnelFoundation.getRequireDateNdancedays());

            //员工评定
            GzEmployeeEvaluation gzEmployeeEvaluation = iGzEmployeeEvaluationService.getOne(new QueryWrapper<GzEmployeeEvaluation>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));
            if (gzEmployeeEvaluation==null || gzEmployeeEvaluation.getMonthlyEvaluationBonus()==null){
                throw new BaseException("请在员工评定，输入月度评定奖金");
            }

            gzTransfer.setMonthlyEvaluationBonus(gzEmployeeEvaluation.getMonthlyEvaluationBonus());

            //考勤管理
            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));
            if (attendanceManagement==null || attendanceManagement.getAttendanceDays()==null){
                throw new BaseException("请在考勤管理,输入应出勤天数");
            }

            GzSalaryLevelTransferWarehouseWorkers salaryLevelTransferWarehouseWorkers = iGzSalaryLevelTransferWarehouseWorkersService.getOne(new QueryWrapper<GzSalaryLevelTransferWarehouseWorkers>().eq("category_level", gzPersonnelFoundation.getSalaryLevel()).eq("subclass_level", gzPersonnelFoundation.getSubclassIevel()));

            // 全勤才有全勤奖
            gzTransfer.setFullAttendanceAward(BigDecimal.valueOf(0));
            if (attendanceManagement.getAttendanceDays().equals(gzPersonnelFoundation.getRequireDateNdancedays())){
                gzTransfer.setFullAttendanceAward(salaryLevelTransferWarehouseWorkers.getFullAttendanceBonus());
            }
            gzTransfer.setAbsenceDays(attendanceManagement.getAbsenceDays());
            gzTransfer.setPaidLeaveCompany(attendanceManagement.getPaidLeaveCompany());

            gzTransfer.setAttendanceDays(attendanceManagement.getAttendanceDays());
            //出勤基本工资=（应出勤天数/基本工资）*实际出勤天数
            gzTransfer.setAttendanceSalary(gzTransfer.getBaseSalary().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            gzTransfer.setAttendancePositionSalary(gzTransfer.getPostWage().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            gzTransfer.setAttendanceManagementAllowance(gzTransfer.getManagementAllowance().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            gzTransfer.setAttendanceHousingAllowance(gzTransfer.getHouseAllowance().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));
            gzTransfer.setAttendanceSocialSecuritySubsidy(gzTransfer.getSocialSecuritySubsidies().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));

            gzTransfer.setPerformanceCoefficient(gzEmployeeEvaluation.getPerformanceCoefficient());

            //按天折算绩效奖金=（绩效奖金*实际出勤天数/应出勤天数）*绩效系数

            if (gzEmployeeEvaluation.getPerformanceCoefficient()==null){
                gzEmployeeEvaluation.setPerformanceCoefficient(new Double(1));
            }

            gzTransfer.setDayAchievementBonus(gzPersonnelFoundation.getAchievementBonus().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(attendanceManagement.getRequireDateNdancedays()),2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(gzEmployeeEvaluation.getPerformanceCoefficient())));
            //按天折算评定奖金=应出勤天数/月度评定奖金）*实际出勤天数
            gzTransfer.setDayEvaluateBonus(gzEmployeeEvaluation.getMonthlyEvaluationBonus().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(attendanceManagement.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));


            gzTransfer.setServiceExperienceAward(salaryLevelTransferWarehouseWorkers.getSeniorityPay());

            gzTransfer.setOvertimePay(attendanceManagement.getOvertimeLate());

            //违纪赔偿
            //gzTransfer.setCompensateFor(attendanceManagement.get());

            gzTransfer.setMealFeeDeduction(attendanceManagement.getMealFeeDeduction());
            gzTransfer.setOtherSubsidies(attendanceManagement.getOtherSubsidies());

            //合计
            gzTransfer.setAmountTo(amountToGzTransfer(gzTransfer));

            //实发工资
            gzTransfer.setActualSalaryPaid(realityGzTransfer(gzTransfer));
            gzTransferList.add(gzTransfer);
        }
        iGzTransferService.saveOrUpdateBatch(gzTransferList);
    }

    private BigDecimal amountToGzTransfer(GzTransfer gzTransfer){
        BigDecimal amountTo=new BigDecimal(0);
        amountTo=amountTo.add(gzTransfer.getAttendanceSalary());
        amountTo=amountTo.add(gzTransfer.getAttendancePositionSalary());
        amountTo=amountTo.add(gzTransfer.getAttendanceManagementAllowance());
        amountTo=amountTo.add(gzTransfer.getAttendanceHousingAllowance());
        amountTo=amountTo.add(gzTransfer.getAttendanceSocialSecuritySubsidy());
        amountTo=amountTo.add(gzTransfer.getDayAchievementBonus());
        amountTo=amountTo.add(gzTransfer.getDayEvaluateBonus());
        amountTo=amountTo.add(gzTransfer.getOvertimePay());
        amountTo=amountTo.add(gzTransfer.getFullAttendanceAward());
        amountTo=amountTo.add(gzTransfer.getServiceExperienceAward());
        amountTo=amountTo.add(gzTransfer.getOtherSubsidies());
        amountTo=amountTo.add(gzTransfer.getCompensateFor());
        amountTo=amountTo.add(gzTransfer.getMealFeeDeduction());
        amountTo=amountTo.add(gzTransfer.getSubsidy());
        return amountTo;

    }

    private BigDecimal realityGzTransfer(GzTransfer gzTransfer){
        BigDecimal reality=new BigDecimal(0);
        reality=reality.add(gzTransfer.getAttendanceSalary());
        reality=reality.add(gzTransfer.getAttendancePositionSalary());
        reality=reality.add(gzTransfer.getAttendanceManagementAllowance());
        reality=reality.add(gzTransfer.getAttendanceHousingAllowance());
        reality=reality.add(gzTransfer.getAttendanceSocialSecuritySubsidy());
        reality=reality.add(gzTransfer.getDayAchievementBonus());
        reality=reality.add(gzTransfer.getDayEvaluateBonus());
        reality=reality.add(gzTransfer.getOvertimePay());
        reality=reality.add(gzTransfer.getFullAttendanceAward());
        reality=reality.add(gzTransfer.getServiceExperienceAward());
        reality=reality.add(gzTransfer.getOtherSubsidies());
        reality=reality.add(gzTransfer.getCompensateFor());
        reality=reality.add(gzTransfer.getMealFeeDeduction());
        reality=reality.add(gzTransfer.getSubsidy());
        return reality;
    }


    //生成仓库工资条
    @Override
    @Transactional
    public void generateWarehousePayroll(Date month, List<GzPersonnelFoundation> gzWarehousePersonnels) {
        //删除  仓库工资条
        iGzWarehousePersonnelService.delelteMonth(month);
        List<GzWarehousePersonnel> warehousePersonnels = new ArrayList<>();
        for (GzPersonnelFoundation gzPersonnelFoundation : gzWarehousePersonnels) {
            GzWarehousePersonnel gzWarehousePersonnel=new GzWarehousePersonnel();
            gzWarehousePersonnel.setUserId(gzPersonnelFoundation.getId());
            gzWarehousePersonnel.setMonth(month);
            gzWarehousePersonnel.setDepartmentName(gzPersonnelFoundation.getDepartmentName());
            gzWarehousePersonnel.setName(gzPersonnelFoundation.getName());
            gzWarehousePersonnel.setBaseSalary(gzPersonnelFoundation.getBasicSalary());
            gzWarehousePersonnel.setPostWage(gzPersonnelFoundation.getPostWage());
            gzWarehousePersonnel.setManagementAllowance(gzPersonnelFoundation.getManagementAllowance());
            gzWarehousePersonnel.setHouseAllowance(gzPersonnelFoundation.getHouseaLlowance());
            gzWarehousePersonnel.setSocialSecuritySubsidies(gzPersonnelFoundation.getSocialSecuritySubsidies());
            gzWarehousePersonnel.setAchievementBonus(gzPersonnelFoundation.getAchievementBonus());
            gzWarehousePersonnel.setEvaluateBonus(gzPersonnelFoundation.getEvaluationCriteriaBonus());
            gzWarehousePersonnel.setRequiredAttendanceDays(gzPersonnelFoundation.getRequireDateNdancedays());
            //考勤管理
            //全勤奖
            // 应出勤天数
            gzWarehousePersonnel.setRequiredAttendanceDays(gzPersonnelFoundation.getRequireDateNdancedays());
            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzPersonnelFoundation.getId()).eq("month",month).eq("department_name",gzPersonnelFoundation.getDepartmentName()));

            if( attendanceManagement==null || attendanceManagement.getAttendanceDays()==null){
                throw new BaseException("请在考勤管理输入出勤天数");
            }
            //满勤 才有满勤奖
            gzWarehousePersonnel.setFullAttendanceAward(BigDecimal.valueOf(0));
            if (attendanceManagement.getAttendanceDays().equals(gzPersonnelFoundation.getRequireDateNdancedays())){
                gzWarehousePersonnel.setFullAttendanceAward(attendanceManagement.getFullAttendanceBonus());
            }

            gzWarehousePersonnel.setAbsenceDays(attendanceManagement.getAbsenceDays());
            gzWarehousePersonnel.setPaidLeaveCompany(attendanceManagement.getPaidLeaveCompany());

            gzWarehousePersonnel.setAttendanceDays(attendanceManagement.getAttendanceDays());
            //出勤基本工资=（基本工资）*(实际出勤天数/应出勤天数)
            gzWarehousePersonnel.setAttendanceSalary(gzPersonnelFoundation.getBasicSalary().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));

            //出勤岗位工资
            gzWarehousePersonnel.setAttendancePositionSalary(gzPersonnelFoundation.getPostWage().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));

            //出勤管理津贴
            gzWarehousePersonnel.setAttendanceManagementAllowance(gzPersonnelFoundation.getManagementAllowance().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));


            //出勤住房津贴=应出勤天数/住房补助）*实际出勤天数
            gzWarehousePersonnel.setAttendanceHousingAllowance(gzPersonnelFoundation.getHouseaLlowance().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));

            //出勤社保补贴
            gzWarehousePersonnel.setAttendanceSocialSecuritySubsidy(gzPersonnelFoundation.getSocialSecuritySubsidies().multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(gzPersonnelFoundation.getRequireDateNdancedays()),2, RoundingMode.HALF_UP));

            GzWarehouseEvaluation warehouseEvaluation = iGzWarehouseEvaluationService.getOne(new QueryWrapper<GzWarehouseEvaluation>().eq("user_id", gzPersonnelFoundation.getId()).eq("month", month).eq("department_name", gzPersonnelFoundation.getDepartmentName()));
            if(warehouseEvaluation==null || warehouseEvaluation.getMonthlyPerformanceBonus()==null){
                throw new BaseException("请先求出月度绩效奖金来");
            }
            /** 月度评定奖金 */
            if (warehouseEvaluation.getMonthlyEvaluationBonus()==null){
                gzWarehousePersonnel.setMonthlyEvaluationBonus(BigDecimal.ZERO);
            }else {
                gzWarehousePersonnel.setMonthlyEvaluationBonus(warehouseEvaluation.getMonthlyEvaluationBonus());
            }


            if (attendanceManagement.getRequireDateNdancedays().equals("0")){
                throw new BaseException("出勤天数 不能为0天");
            }

            BigDecimal monthlyPerformanceByDays = BigDecimal.valueOf(gzPersonnelFoundation.getPerformanceCoefficient()).multiply(BigDecimal.valueOf(attendanceManagement.getAttendanceDays())).divide(BigDecimal.valueOf(attendanceManagement.getRequireDateNdancedays()), 2, RoundingMode.HALF_UP);
            gzWarehousePersonnel.setMonthlyPerformanceBonus(monthlyPerformanceByDays);

            GzTotalSalesOfTheCompany gzTotalSalesOfTheCompany = iGzTotalSalesOfTheCompanyService.getOne(new QueryWrapper<GzTotalSalesOfTheCompany>().eq("month", month));
            /** 月平均绩效金额 */
            BigDecimal monthlyAveragePerformanceAmount = gzTotalSalesOfTheCompany.getMonthlyAveragePerformanceAmount();
            /** 当月按天数绩效 */
            Double monthlyPerformanceByDays1 = warehouseEvaluation.getMonthlyPerformanceByDays();

            //计算月度绩效奖金
            gzWarehousePersonnel.setMonthlyPerformanceBonus(new BigDecimal(monthlyPerformanceByDays1).multiply(monthlyAveragePerformanceAmount));

            /** 评定标准奖金 */
            gzWarehousePersonnel.setMonthlyEvaluationBonus(warehouseEvaluation.getMonthlyEvaluationBonus());

            /** 加班工资 全勤奖  */
            gzWarehousePersonnel.setOvertimePay(attendanceManagement.getOvertimeLate());

            gzWarehousePersonnel.setMealFeeDeduction(attendanceManagement.getMealFeeDeduction());
            gzWarehousePersonnel.setServiceExperienceAward(gzPersonnelFoundation.getServiceExperienceAward());
            gzWarehousePersonnel.setOtherSubsidies(gzPersonnelFoundation.getOtherSubsidies());

            GzWarehouseWorkerSalaryLevel salaryLevel = iGzWarehouseWorkerSalaryLevelService.getOne(new QueryWrapper<GzWarehouseWorkerSalaryLevel>().eq("category_level", gzPersonnelFoundation.getSalaryLevel()).eq("subclass_level", gzPersonnelFoundation.getSubclassIevel()));


            /** 违纪赔偿 餐费扣款  其他扣款 */
            gzWarehousePersonnel.setMealFeeDeduction(attendanceManagement.getMealFeeDeduction());
            gzWarehousePersonnel.setOtherSubsidies(attendanceManagement.getOtherSubsidies());
            gzWarehousePersonnel.setCompensateFor(attendanceManagement.getLateDeduction());


            //合计
            gzWarehousePersonnel.setAmountTo(amountToGzWarehousePersonnel(gzWarehousePersonnel));
            //实际
            gzWarehousePersonnel.setActualSalaryPaid(realityGzWarehousePersonnelr(gzWarehousePersonnel));
            warehousePersonnels.add(gzWarehousePersonnel);
        }

        iGzWarehousePersonnelService.saveOrUpdateBatch(warehousePersonnels);

    }
    private BigDecimal amountToGzWarehousePersonnel(GzWarehousePersonnel gzWarehousePersonnel){
        BigDecimal amountTo=new BigDecimal(0);

        /** 出勤基本工资 */
        amountTo=amountTo.add(gzWarehousePersonnel.getAttendanceSalary());
        /** 出勤岗位工资 */
        amountTo=amountTo.add(gzWarehousePersonnel.getAttendancePositionSalary());
        /** 出勤管理津贴 */
        amountTo=amountTo.add(gzWarehousePersonnel.getAttendanceManagementAllowance());
        /** 出勤住房津贴 */
        amountTo=amountTo.add(gzWarehousePersonnel.getAttendanceHousingAllowance());
        /** 出勤社保补贴 */
        amountTo=amountTo.add(gzWarehousePersonnel.getAttendanceSocialSecuritySubsidy());
        /** 月度绩效奖金 */
        amountTo=amountTo.add(gzWarehousePersonnel.getMonthlyPerformanceBonus());
        /** 月度评定奖金 */
        if (gzWarehousePersonnel.getMonthlyEvaluationBonus()==null){
            amountTo=amountTo.add(BigDecimal.ZERO);
        }else {
            amountTo=amountTo.add(gzWarehousePersonnel.getMonthlyEvaluationBonus());
        }

        /** 加班工资 */
        amountTo=amountTo.add(gzWarehousePersonnel.getOvertimePay());
        /** 全勤奖 */
        amountTo=amountTo.add(gzWarehousePersonnel.getFullAttendanceAward());
        /** 工龄奖 */
        amountTo=amountTo.add(gzWarehousePersonnel.getServiceExperienceAward());
        /** 其他补贴 */
        amountTo=amountTo.add(gzWarehousePersonnel.getOtherSubsidies());
        /** 违纪赔偿 */
        amountTo=amountTo.add(gzWarehousePersonnel.getCompensateFor());
        /** 餐费扣款 */
        amountTo=amountTo.add(gzWarehousePersonnel.getMealFeeDeduction());
        /** 补贴/社保个人部分   其他扣款*/
        amountTo=amountTo.add(gzWarehousePersonnel.getSubsidy());
        return amountTo;

    }

    private BigDecimal realityGzWarehousePersonnelr(GzWarehousePersonnel gzWarehousePersonnel){
        BigDecimal reality=new BigDecimal(0);
        reality=reality.add(gzWarehousePersonnel.getAttendanceSalary());
        reality=reality.add(gzWarehousePersonnel.getAttendancePositionSalary());
        reality=reality.add(gzWarehousePersonnel.getAttendanceManagementAllowance());
        reality=reality.add(gzWarehousePersonnel.getAttendanceHousingAllowance());
        reality=reality.add(gzWarehousePersonnel.getAttendanceSocialSecuritySubsidy());
        //reality=reality.add(gzWarehousePersonnel.getMonthlyEvaluationBonus());
        reality=reality.add(gzWarehousePersonnel.getMonthlyPerformanceBonus());

        reality=reality.add(gzWarehousePersonnel.getOvertimePay());
        reality=reality.add(gzWarehousePersonnel.getFullAttendanceAward());
        reality=reality.add(gzWarehousePersonnel.getServiceExperienceAward());
        reality=reality.add(gzWarehousePersonnel.getOtherSubsidies());
        reality=reality.add(gzWarehousePersonnel.getCompensateFor());
        reality=reality.add(gzWarehousePersonnel.getMealFeeDeduction());
        reality=reality.add(gzWarehousePersonnel.getSubsidy());
        return reality;
    }


    //生成当月办公室及档口人事数据
    @Override
    public void generateSalaryBill( List<GzOfficeSalary> gzOfficeSalaries){
        List<GzPersonnelVersion> gzPersonnelVersions = new ArrayList<>();
        for (GzOfficeSalary gzOfficeSalary : gzOfficeSalaries){
            GzPersonnelVersion personnelVersion=new GzPersonnelVersion();
            GzHolidays gzHolidays = iGzHolidaysService.getOne(new LambdaQueryWrapper<GzHolidays>().eq(GzHolidays::getMonth, gzOfficeSalary.getMonth()).eq(GzHolidays::getDelStatus, YesNoEnum.NO.getKey()));
            personnelVersion.setOfficeSalaryId(gzOfficeSalary.getId());
            personnelVersion.setMonth(gzOfficeSalary.getMonth());
            personnelVersion.setDepartmentName(gzOfficeSalary.getDepartmentName());
            personnelVersion.setName(gzOfficeSalary.getName());
            /** 基本工资 */
            personnelVersion.setBaseSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()));
            /** 计薪天数 */
            personnelVersion.setSalaryDays(Double.parseDouble(gzHolidays.getSalaryCalculationDay()));
            /** 公司带薪假 */
            if (gzOfficeSalary.getPaidLeaveCompany()!=null){
                personnelVersion.setPaidLeave(gzOfficeSalary.getPaidLeaveCompany().doubleValue());
            }
            /** 实际出勤天数 ===出勤天数(工作日)减去缺勤天数得出这个数 */
            personnelVersion.setAttendanceDays(Double.parseDouble(gzHolidays.getWeekday())-gzOfficeSalary.getAbsenceDays().doubleValue());

            if (gzOfficeSalary.getAbsenceDays()!=null){
                /** 缺勤天数 */
                personnelVersion.setAbsenceDays(gzOfficeSalary.getAbsenceDays().doubleValue());
            }
            /** 出勤工资 */
            personnelVersion.setAttendanceSalary(new BigDecimal(gzHolidays.getAttendanceSalary()));

            /** 公司带薪假工资 ：基本工资/21.75*公司带薪假*出勤天数比例得出， */
            personnelVersion.setPaidLeaveSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()).divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).multiply(gzOfficeSalary.getPaidLeaveCompany()).multiply(new BigDecimal(gzHolidays.getAttendanceDaysRatio())));
            /** 国家节假日带薪工资 */
            personnelVersion.setHolidayWages(new BigDecimal(gzHolidays.getPaidsalaryDuringNationalHolidays()));

            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzOfficeSalary.getUserId()).eq("month",gzOfficeSalary.getMonth()).eq("department_name",gzOfficeSalary.getDepartmentName()));
            /** (（加班小时）加班平时)  按考勤加班实际填写，考勤表工作日加班*/
            //personnelVersion.setOvertimeUsually(attendanceManagement.getOvertimeLate())
            /** （（加班小时）加班周六日） ：真实出勤天数减去计薪天数。然后仓库及中转人员*9，办公室人员*8得出。 */
            personnelVersion.setOvertimeWeek((attendanceManagement.getAttendanceDays()-personnelVersion.getSalaryDays())*8);
            /** （（加班小时）加班节日） */
            //personnelVersion.setOvertimeHoliday();

            /** ((加班工资)加班平时) */
            //personnelVersion.setOvertimePayUsually(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeUsually()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班周六日) */
            personnelVersion.setOvertimePayWeek(personnelVersion.getBaseSalary().divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(8), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeWeek()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班节日) */
            //personnelVersion.setOvertimePayHoliday(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf( personnelVersion.getOvertimeHoliday()).multiply(new BigDecimal(2))));

            /** 全勤奖 */
            personnelVersion.setFullAttendanceAward(gzOfficeSalary.getFullAttendanceAward());

            personnelVersion.setPurchaseSocialSecurity(gzOfficeSalary.getSubsidy());

            /** 五险一金补贴 */
            //personnelVersion.setFiveOneSubsidy();

            /** 应发工资 */
            personnelVersion.setSalariesPayable(AmountToOffice(personnelVersion));
            //personnelVersion.setSalariesPayable(gzOfficeSalary.getAmountTo());
            /** 违纪赔偿 */
            personnelVersion.setCompensateFor(gzOfficeSalary.getLateDeduction());
            /** 餐费扣款 */
            personnelVersion.setMealFeeDeduction(gzOfficeSalary.getMealFeeDeduction());
            /** 工资实发 =应发工资-违纪赔偿-餐费扣款 */
            BigDecimal actualSalaryPaid = personnelVersion.getSalariesPayable().subtract(personnelVersion.getCompensateFor()).subtract(personnelVersion.getMealFeeDeduction());
            personnelVersion.setActualSalaryPaid(actualSalaryPaid);

            personnelVersion.setSignee(gzOfficeSalary.getName());

            /** 岗位绩效奖金  //用实际工资减去实发工资得出。 */
            if (gzOfficeSalary.getActualSalaryPaid()!=null){
                personnelVersion.setJobPerformanceBonus(gzOfficeSalary.getActualSalaryPaid().subtract(personnelVersion.getActualSalaryPaid()));
            }
            gzPersonnelVersions.add(personnelVersion);

        }

        iGzPersonnelVersionService.saveBatch(gzPersonnelVersions);
    }

    private BigDecimal AmountToOffice(GzPersonnelVersion personnelVersion) {
        BigDecimal salariesPayable = new BigDecimal("0");

        if (personnelVersion.getAttendanceSalary()!=null){
            /** 出勤工资 */
            salariesPayable=salariesPayable.add(personnelVersion.getAttendanceSalary());
        }

        if (personnelVersion.getPaidLeaveSalary()!=null){
            /** 公司带薪假工资 */
            salariesPayable=salariesPayable.add(personnelVersion.getPaidLeaveSalary());
        }
        if (personnelVersion.getHolidayWages()!=null){
            /** 国家节假日带薪工资 */
            salariesPayable=salariesPayable.add(personnelVersion.getHolidayWages());
        }
        if (personnelVersion.getOvertimePayUsually()!=null){
            /** ((加班工资)加班平时) */
            salariesPayable=salariesPayable.add(personnelVersion.getOvertimePayUsually());
        }
        if (personnelVersion.getOvertimePayWeek()!=null){
            /** ((加班工资)加班周六日) */
            salariesPayable=salariesPayable.add(personnelVersion.getOvertimePayWeek());
        }
        if (personnelVersion.getOvertimePayHoliday()!=null){
            /** ((加班工资)加班节日) */
            salariesPayable=salariesPayable.add(personnelVersion.getOvertimePayHoliday());
        }
        //缺工龄奖
        if (personnelVersion.getJobPerformanceBonus()!=null){
            /** 岗位绩效奖金 */
            salariesPayable=salariesPayable.add(personnelVersion.getJobPerformanceBonus());
        }

        if (personnelVersion.getFullAttendanceAward()!=null){
            /** 全勤奖 */
            salariesPayable=salariesPayable.add(personnelVersion.getFullAttendanceAward());
        }

        if (personnelVersion.getPurchaseSocialSecurity()!=null){
            /** 购买社保 */
            salariesPayable=salariesPayable.add(personnelVersion.getPurchaseSocialSecurity());
        }

        if (personnelVersion.getFiveOneSubsidy()!=null){
            /** 五险一金补贴 */
            salariesPayable=salariesPayable.add(personnelVersion.getFiveOneSubsidy());
        }
        return salariesPayable;
    }


    //中转生成工资条人事版本
    @Override
    public void generateSalaryBillMatter(List<GzTransfer> gzTransferList){
        List<GzPersonnelVersion> gzPersonnelVersions = new ArrayList<>();
        for (GzTransfer gzTransfer : gzTransferList){
            GzPersonnelVersion personnelVersion=new GzPersonnelVersion();
            GzHolidays gzHolidays = iGzHolidaysService.getOne(new LambdaQueryWrapper<GzHolidays>().eq(GzHolidays::getMonth, gzTransfer.getMonth()).eq(GzHolidays::getDelStatus, YesNoEnum.NO.getKey()));
            personnelVersion.setOfficeSalaryId(gzTransfer.getId());
            personnelVersion.setMonth(gzTransfer.getMonth());
            personnelVersion.setDepartmentName(gzTransfer.getDepartmentName());
            personnelVersion.setName(gzTransfer.getName());
            /** 基本工资 */
            personnelVersion.setBaseSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()));
            /** 计薪天数 */
            personnelVersion.setSalaryDays(Double.parseDouble(gzHolidays.getSalaryCalculationDay()));
            /** 公司带薪假 */
            if (gzTransfer.getPaidLeaveCompany()!=null){
                personnelVersion.setPaidLeave(gzTransfer.getPaidLeaveCompany().doubleValue());
            }
            /** 实际出勤天数 ===出勤天数(工作日)减去缺勤天数得出这个数 */
            personnelVersion.setAttendanceDays(Double.parseDouble(gzHolidays.getWeekday())-gzTransfer.getAbsenceDays().doubleValue());

            if (gzTransfer.getAbsenceDays()!=null){
                /** 缺勤天数 */
                personnelVersion.setAbsenceDays(gzTransfer.getAbsenceDays().doubleValue());
            }
            /** 出勤工资 */
            personnelVersion.setAttendanceSalary(new BigDecimal(gzHolidays.getAttendanceSalary()));

            /** 公司带薪假工资 ：基本工资/21.75*公司带薪假*出勤天数比例得出， */
            personnelVersion.setPaidLeaveSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()).divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).multiply(gzTransfer.getPaidLeaveCompany()).multiply(new BigDecimal(gzHolidays.getAttendanceDaysRatio())));
            /** 国家节假日带薪工资 */
            personnelVersion.setHolidayWages(new BigDecimal(gzHolidays.getPaidsalaryDuringNationalHolidays()));

            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzTransfer.getUserId()).eq("month",gzTransfer.getMonth()).eq("department_name",gzTransfer.getDepartmentName()));
            /** (（加班小时）加班平时)  按考勤加班实际填写，考勤表工作日加班*/
            //personnelVersion.setOvertimeUsually(attendanceManagement.getOvertimeLate())
            /** （（加班小时）加班周六日） ：真实出勤天数减去计薪天数。然后仓库及中转人员*9，办公室人员*8得出。 */
            personnelVersion.setOvertimeWeek((attendanceManagement.getAttendanceDays()-personnelVersion.getSalaryDays())*8);
            /** （（加班小时）加班节日） */
            //personnelVersion.setOvertimeHoliday();

            /** ((加班工资)加班平时) */
            //personnelVersion.setOvertimePayUsually(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeUsually()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班周六日) */
            personnelVersion.setOvertimePayWeek(personnelVersion.getBaseSalary().divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(8), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeWeek()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班节日) */
            //personnelVersion.setOvertimePayHoliday(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf( personnelVersion.getOvertimeHoliday()).multiply(new BigDecimal(2))));

            /** 全勤奖 */
            personnelVersion.setFullAttendanceAward(gzTransfer.getFullAttendanceAward());

            personnelVersion.setPurchaseSocialSecurity(gzTransfer.getSubsidy());

            /** 五险一金补贴 */
            //personnelVersion.setFiveOneSubsidy();

            /** 应发工资 */
            personnelVersion.setSalariesPayable(AmountToOffice(personnelVersion));
            //personnelVersion.setSalariesPayable(gzOfficeSalary.getAmountTo());
            /** 违纪赔偿 */
            personnelVersion.setCompensateFor(gzTransfer.getCompensateFor());
            /** 餐费扣款 */
            personnelVersion.setMealFeeDeduction(gzTransfer.getMealFeeDeduction());
            /** 工资实发 =应发工资-违纪赔偿-餐费扣款 */
            BigDecimal actualSalaryPaid = personnelVersion.getSalariesPayable().subtract(personnelVersion.getCompensateFor()).subtract(personnelVersion.getMealFeeDeduction());
            personnelVersion.setActualSalaryPaid(actualSalaryPaid);

            personnelVersion.setSignee(gzTransfer.getName());

            /** 岗位绩效奖金  //用实际工资减去实发工资得出。 */
            if (gzTransfer.getActualSalaryPaid()!=null){
                personnelVersion.setJobPerformanceBonus(gzTransfer.getActualSalaryPaid().subtract(personnelVersion.getActualSalaryPaid()));
            }
            gzPersonnelVersions.add(personnelVersion);


        }

        iGzPersonnelVersionService.saveBatch(gzPersonnelVersions);
    }

    //仓库生成工资条人事版本

    @Override
    public void  generateWarehouse(List<GzWarehousePersonnel> warehousePersonnels){
        List<GzPersonnelVersion> gzPersonnelVersions = new ArrayList<>();
        for (GzWarehousePersonnel gzWarehousePersonnel : warehousePersonnels){
            GzPersonnelVersion personnelVersion=new GzPersonnelVersion();
            GzHolidays gzHolidays = iGzHolidaysService.getOne(new LambdaQueryWrapper<GzHolidays>().eq(GzHolidays::getMonth, gzWarehousePersonnel.getMonth()).eq(GzHolidays::getDelStatus, YesNoEnum.NO.getKey()));
            personnelVersion.setOfficeSalaryId(gzWarehousePersonnel.getId());
            personnelVersion.setMonth(gzWarehousePersonnel.getMonth());
            personnelVersion.setDepartmentName(gzWarehousePersonnel.getDepartmentName());
            personnelVersion.setName(gzWarehousePersonnel.getName());
            /** 基本工资 */
            personnelVersion.setBaseSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()));
            /** 计薪天数 */
            personnelVersion.setSalaryDays(Double.parseDouble(gzHolidays.getSalaryCalculationDay()));
            /** 公司带薪假 */
            if (gzWarehousePersonnel.getPaidLeaveCompany()!=null){
                personnelVersion.setPaidLeave(gzWarehousePersonnel.getPaidLeaveCompany().doubleValue());
            }
            /** 实际出勤天数 ===出勤天数(工作日)减去缺勤天数得出这个数 */
            personnelVersion.setAttendanceDays(Double.parseDouble(gzHolidays.getWeekday())-gzWarehousePersonnel.getAbsenceDays().doubleValue());

            if (gzWarehousePersonnel.getAbsenceDays()!=null){
                /** 缺勤天数 */
                personnelVersion.setAbsenceDays(gzWarehousePersonnel.getAbsenceDays().doubleValue());
            }
            /** 出勤工资 */
            personnelVersion.setAttendanceSalary(new BigDecimal(gzHolidays.getAttendanceSalary()));

            /** 公司带薪假工资 ：基本工资/21.75*公司带薪假*出勤天数比例得出， */
            personnelVersion.setPaidLeaveSalary(new BigDecimal(gzHolidays.getBasicSalaryGuangzhou()).divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).multiply(gzWarehousePersonnel.getPaidLeaveCompany()).multiply(new BigDecimal(gzHolidays.getAttendanceDaysRatio())));
            /** 国家节假日带薪工资 */
            personnelVersion.setHolidayWages(new BigDecimal(gzHolidays.getPaidsalaryDuringNationalHolidays()));

            GzAttendanceManagement attendanceManagement = iGzAttendanceManagementService.getOne(new QueryWrapper<GzAttendanceManagement>().eq("user_id",gzWarehousePersonnel.getUserId()).eq("month",gzWarehousePersonnel.getMonth()).eq("department_name",gzWarehousePersonnel.getDepartmentName()));
            /** (（加班小时）加班平时)  按考勤加班实际填写，考勤表工作日加班*/
            //personnelVersion.setOvertimeUsually(attendanceManagement.getOvertimeLate())
            /** （（加班小时）加班周六日） ：真实出勤天数减去计薪天数。然后仓库及中转人员*9，办公室人员*8得出。 */
            personnelVersion.setOvertimeWeek((attendanceManagement.getAttendanceDays()-personnelVersion.getSalaryDays())*8);
            /** （（加班小时）加班节日） */
            //personnelVersion.setOvertimeHoliday();

            /** ((加班工资)加班平时) */
            //personnelVersion.setOvertimePayUsually(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeUsually()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班周六日) */
            personnelVersion.setOvertimePayWeek(personnelVersion.getBaseSalary().divide(BigDecimal.valueOf(21.75), 2, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(8), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(personnelVersion.getOvertimeWeek()).multiply(new BigDecimal(2))));

            /** ((加班工资)加班节日) */
            //personnelVersion.setOvertimePayHoliday(personnelVersion.getBaseSalary().divide(new BigDecimal(21.75)).divide(new BigDecimal(8)).multiply(BigDecimal.valueOf( personnelVersion.getOvertimeHoliday()).multiply(new BigDecimal(2))));

            /** 全勤奖 */
            personnelVersion.setFullAttendanceAward(gzWarehousePersonnel.getFullAttendanceAward());

            personnelVersion.setPurchaseSocialSecurity(gzWarehousePersonnel.getSubsidy());

            /** 五险一金补贴 */
            //personnelVersion.setFiveOneSubsidy();

            /** 应发工资 */
            personnelVersion.setSalariesPayable(AmountToOffice(personnelVersion));
            //personnelVersion.setSalariesPayable(gzOfficeSalary.getAmountTo());
            /** 违纪赔偿 */
            personnelVersion.setCompensateFor(gzWarehousePersonnel.getCompensateFor());
            /** 餐费扣款 */
            personnelVersion.setMealFeeDeduction(gzWarehousePersonnel.getMealFeeDeduction());
            /** 工资实发 =应发工资-违纪赔偿-餐费扣款 */
            BigDecimal actualSalaryPaid = personnelVersion.getSalariesPayable().subtract(personnelVersion.getCompensateFor()).subtract(personnelVersion.getMealFeeDeduction());
            personnelVersion.setActualSalaryPaid(actualSalaryPaid);

            personnelVersion.setSignee(gzWarehousePersonnel.getName());

            /** 岗位绩效奖金  //用实际工资减去实发工资得出。 */
            if (gzWarehousePersonnel.getActualSalaryPaid()!=null){
                personnelVersion.setJobPerformanceBonus(gzWarehousePersonnel.getActualSalaryPaid().subtract(personnelVersion.getActualSalaryPaid()));
            }
            gzPersonnelVersions.add(personnelVersion);

        }

        iGzPersonnelVersionService.saveBatch(gzPersonnelVersions);
    }

}